package com.xbongbong.paas.connection.service.imp;

import com.alibaba.dingtalk.openapi.exception.OApiException;
import com.alibaba.dingtalk.openapi.helper.AuthHelper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dingtalkconnector_1_0.models.PullDataByPageHeaders;
import com.aliyun.dingtalkconnector_1_0.models.PullDataByPageRequest;
import com.aliyun.dingtalkconnector_1_0.models.PullDataByPageResponse;
import com.aliyun.dingtalkconnector_1_0.models.PullDataByPageResponseBody;
import com.aliyun.dingtalkconnector_1_0.models.SyncDataHeaders;
import com.aliyun.dingtalkconnector_1_0.models.SyncDataRequest;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.xbongbong.callback.service.ConnectorConfigService;
import com.xbongbong.callback.service.ConnectorProducerService;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.connection.connector.service.PaymentSheetStandardConnector;
import com.xbongbong.paas.connection.enums.BusinessCodePrefixEnum;
import com.xbongbong.paas.connection.help.ConnectorFormatHelper;
import com.xbongbong.paas.connection.pojo.connector.AttributeStandardPojo;
import com.xbongbong.paas.connection.pojo.connector.ContractStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.CustomerStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.DdContractStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.DdCustomerStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.DdOpportunityStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.DdPaymentSheetStandardActionPojo;
import com.xbongbong.paas.connection.pojo.connector.DdPaymentSheetStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.DdPaymentStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.DdProductCategoryStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.DdProductStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.DdStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.DdWarehouseStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.ModelStandardPojo;
import com.xbongbong.paas.connection.pojo.connector.OpportunityStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.OrderSettlementPojo;
import com.xbongbong.paas.connection.pojo.connector.PaymentSheetStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.PaymentStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.PriceStandardPojo;
import com.xbongbong.paas.connection.pojo.connector.ProductCategoryStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.ProductStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.ProductStandardPojo;
import com.xbongbong.paas.connection.pojo.connector.StmtPojo;
import com.xbongbong.paas.connection.pojo.connector.WarehouseStandardFormatPojo;
import com.xbongbong.paas.connection.service.ConnectorService;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PaymentSheetTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.MultiUnitItemPoJo;
import com.xbongbong.paas.field.UnitItemPoJo;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.help.subform.TransferSubFormHelper;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.ProductFieldPojo;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.thread.TransmittableThreadLocalUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.connector.pojo.dto.ConnectorRabbitMqDTO;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ContractProductEntity;
import com.xbongbong.saas.domain.entity.ContractUserEntity;
import com.xbongbong.saas.domain.entity.CustomerUserEntity;
import com.xbongbong.saas.domain.entity.OpportunityUserEntity;
import com.xbongbong.saas.domain.entity.ProductCategoryEntity;
import com.xbongbong.saas.domain.entity.UserTeamEntity;
import com.xbongbong.saas.domain.entity.ext.ContactEntityExt;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.CustomerEntityExt;
import com.xbongbong.saas.domain.entity.ext.OpportunityEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.ProductEntityExt;
import com.xbongbong.saas.domain.entity.ext.WarehouseEntityExt;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.SheetAloneEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.WarehouseEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.enums.dictionary.PaymentStatusEnum;
import com.xbongbong.saas.enums.subform.ContractProductSubFormEnum;
import com.xbongbong.saas.help.FundHelp;
import com.xbongbong.saas.help.SaasFormHelp;
import com.xbongbong.saas.model.ContactModel;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.ContractUserModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.model.DataDictionaryModel;
import com.xbongbong.saas.model.OpportunityModel;
import com.xbongbong.saas.model.OpportunityUserModel;
import com.xbongbong.saas.model.PaymentModel;
import com.xbongbong.saas.model.PaymentSheetModel;
import com.xbongbong.saas.model.PaymentUserModel;
import com.xbongbong.saas.model.ProductCategoryModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.model.WarehouseModel;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.DdModelEnum;
import com.xbongbong.sys.enums.DdTriggerEnum;
import com.xbongbong.sys.model.UserModel;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

/**
 * 连接器触发器
 * 创建时间 2020/12/15 11:04 AM
 * 修改时间 2020/12/15 11:04 AM
 * @author chy
 */
@Service("connectorService")
public class ConnectorServiceImpl implements ConnectorService {
    private static final Logger LOG = LoggerFactory.getLogger(ConnectorServiceImpl.class);

    @Resource
    private CustomerModel customerModel;
    @Resource
    private ContactModel contactModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private ProductModel productModel;
    @Resource
    private WarehouseModel warehouseModel;
    @Resource
    private ProductCategoryModel productCategoryModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private AuthHelper authHelper;
    @Resource
    private SaasFormHelp saasFormHelp;
    @Resource
    private ConnectorFormatHelper connectorFormatHelper;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private TransferSubFormHelper transferSubFormHelper;
    @Resource
    private CustomerUserModel customerUserModel;
    @Resource
    private ContractUserModel contractUserModel;
    @Resource
    private ConnectorConfigService connectorConfigService;
    @Resource
    private DataDictionaryModel dataDictionaryModel;
    @Resource
    private PaymentModel paymentModel;
    @Resource
    private PaymentUserModel paymentUserModel;
    @Resource
    private UserModel userModel;
    @Resource
    private PaymentSheetModel paymentSheetModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private FundHelp fundHelp;
    @Resource
    private PaymentSheetStandardConnector paymentSheetStandardConnector;
    @Resource
    private ConnectorProducerService connectorProducerService;
    @Resource
    private OpportunityModel opportunityModel;
    @Resource
    private OpportunityUserModel opportunityUserModel;
    @Resource
    private MongoLogHelp mongoLogHelp;

    @Override
    public void triggerSend(ConnectorRabbitMqDTO connectorRabbitMqDTO) throws XbbException{
        contactToCustomerDto(connectorRabbitMqDTO);
        LOG.info("triggerSend connectorRabbitMqDTO:" + connectorRabbitMqDTO);
        String corpid = connectorRabbitMqDTO.getCorpid();
        XbbRefTypeEnum xbbRefTypeEnum = connectorRabbitMqDTO.getXbbRefTypeEnum();
        String operate = connectorRabbitMqDTO.getOperate();
        List<Long> dataIdList = connectorRabbitMqDTO.getDataIdList();
        String accessToken = null;
        try {
            accessToken = authHelper.getAccessToken(corpid);
        } catch (OApiException e) {
            e.printStackTrace();
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100125);
        }
        try {
            if (connectorConfigService.hasStandardTrigger(corpid, xbbRefTypeEnum)) {
                LOG.info("hasStandardTrigger");
                for (Long dataId : dataIdList) {
                    triggersDataSync(corpid, xbbRefTypeEnum, operate, dataId, accessToken);
                }
            }
        } catch (Exception e) {
            LOG.error("triggerSend 失败:", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100126);
        }
    }

    /**
     * 联系人被整合在客户中，联系人变更即客户修改
     * @param connectorRabbitMqDTO
     */
    private void contactToCustomerDto(ConnectorRabbitMqDTO connectorRabbitMqDTO) {
        XbbRefTypeEnum xbbRefTypeEnum = connectorRabbitMqDTO.getXbbRefTypeEnum();
        if (!Objects.equals(xbbRefTypeEnum, XbbRefTypeEnum.CONTACT)) {
            return;
        }
        String corpid = connectorRabbitMqDTO.getCorpid();
        List<Long> dataIdList = connectorRabbitMqDTO.getDataIdList();
        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);
        param.put("idIn", dataIdList);
        List<ContactEntityExt> contacts = contactModel.findEntitysWithoutSub(param);
        Set<Long> customerIdSet = new HashSet<>();
        for (ContactEntityExt contact : contacts) {
            JSONObject data = contact.getData();
            Long customerId = data.getLong(ContactEnum.CUSTOMER_NAME.getAttr());
            if (Objects.nonNull(customerId)) {
                customerIdSet.add(customerId);
            }
        }
        dataIdList = new ArrayList<>(customerIdSet);
        connectorRabbitMqDTO.setXbbRefTypeEnum(XbbRefTypeEnum.CUSTOMER);
        connectorRabbitMqDTO.setOperate(OperateTypeEnum.EDIT.getAlias());
        connectorRabbitMqDTO.setDataIdList(dataIdList);
    }

    @Async(value = "connectorPullDataThreadPool")
    @Override
    public void pullData(String corpid) throws Exception {
        LOG.info("connectorPullDataThreadPool pullData");
        TransmittableThreadLocalUtil.setConnectorValue();
        String modelId = DdModelEnum.STANDARD_PAYMENT_SHEET_MODEL.getModelId();
        Long maxDatetime = DateTimeUtil.getInt() * 1000L;
        String nextToken = null;
        Long pageSize = 100L;
        boolean flag = true;
        while (flag) {
            Config config = new Config();
            config.protocol = "https";
            config.regionId = "central";
            com.aliyun.dingtalkconnector_1_0.Client client = new com.aliyun.dingtalkconnector_1_0.Client(config);
            PullDataByPageHeaders pullDataByPageHeaders = new PullDataByPageHeaders();
            pullDataByPageHeaders.xAcsDingtalkAccessToken = authHelper.getAccessToken(corpid);
            LOG.info("corpid:" + corpid + " modelId:" + modelId + " nextToken:" + nextToken + " pageSize:" + pageSize);
            PullDataByPageRequest pullDataByPageRequest = new PullDataByPageRequest()
                    .setDataModelId(modelId)
                    .setAppId(ProBaseConfig.getAppId())
                    .setDatetimeFilterField("dataGmtCreate")
//                .setMinDatetime(1623900250117L)
                    .setMaxDatetime(maxDatetime)
                    .setNextToken(nextToken)
                    .setMaxResults(pageSize);
            try {
                PullDataByPageResponse pullDataByPageResponse = client.pullDataByPageWithOptions(pullDataByPageRequest, pullDataByPageHeaders, new RuntimeOptions());
                List<PullDataByPageResponseBody.PullDataByPageResponseBodyList> list = pullDataByPageResponse.getBody().getList();
                if (Objects.isNull(list) || list.size() < pageSize) {
                    flag = false;
                }
                nextToken = pullDataByPageResponse.getBody().getNextToken();
                savePaymentSheetList(corpid, list);
            } catch (TeaException err) {
                if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                    // err 中含有 code 和 message 属性，可帮助开发定位问题
                    LOG.error("err.code:" + err.code + " err.message:" + err.message);
                    flag = false;
                }
            } catch (Exception _err) {
                TeaException err = new TeaException(_err.getMessage(), _err);
                if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                    // err 中含有 code 和 message 属性，可帮助开发定位问题
                    LOG.error("err.code:" + err.code + " err.message:" + err.message);
                    flag = false;
                }
            }
        }
    }
    @Async(value = "connectorPushDataThreadPool")
    @Override
    public void pushData(String corpid, Integer totalNum) throws Exception {
        totalNum = (Objects.isNull(totalNum) || Objects.equals(totalNum, 0)) ? 100 : totalNum;
        Integer pageNum = 100;
        long now = DateTimeUtil.getInt();

        Integer productCategoryPage = 1;
        Integer productCategoryPageNum = totalNum;
        boolean hasProductCategory = true;
        Map<String, Object> productCategoryMap = new HashMap<>();
        productCategoryMap.put("corpid", corpid);
        productCategoryMap.put("updateTimeEnd", now);
        productCategoryMap.put("del", 0);
        productCategoryMap.put("pageNum", pageNum);
        productCategoryMap.put("orderByStr", "update_time desc");
        while (productCategoryPageNum > 0 && hasProductCategory) {
            LOG.info("productCategoryPage:" + productCategoryPage);
            productCategoryMap.put("start", (productCategoryPage - 1) * pageNum);
            List<ProductCategoryEntity> productCategoryList = productCategoryModel.findEntitys(productCategoryMap);
            for (ProductCategoryEntity productCategory : productCategoryList) {
                LOG.info("productCategory.getId():" + productCategory.getId());
                connectorProducerService.triggerSend(corpid, XbbRefTypeEnum.PRODUCT_CATEGORY, OperateTypeEnum.NEW.getAlias(), productCategory.getId());
            }
            productCategoryPageNum = productCategoryPageNum - productCategoryList.size();
            hasProductCategory = !productCategoryList.isEmpty();
            productCategoryPage++;

        }

        Integer customerPage = 1;
        Integer customerPageNum = totalNum;
        boolean hasCustomer = true;
        Map<String, Object> customerMap = new HashMap<>();
        customerMap.put("corpid", corpid);
        customerMap.put("updateTimeEnd", now);
        customerMap.put("del", 0);
        customerMap.put("pageNum", pageNum);
        customerMap.put("orderByStr", "update_time desc");
        while (customerPageNum > 0 && hasCustomer) {
            LOG.info("customerPage:" + customerPage);
            customerMap.put("start", (customerPage - 1) * pageNum);
            List<CustomerEntityExt> customerList = customerModel.findEntitys(customerMap);
            for (CustomerEntityExt customer : customerList) {
                LOG.info("customer.getId():" + customer.getId());
                connectorProducerService.triggerSend(corpid, XbbRefTypeEnum.CUSTOMER, OperateTypeEnum.NEW.getAlias(), customer.getId());
            }
            customerPageNum = customerPageNum - customerList.size();
            hasCustomer = !customerList.isEmpty();
            customerPage++;
        }

        Integer warehousePage = 1;
        Integer warehousePageNum = totalNum;
        boolean hasWarehouse = true;
        Map<String, Object> warehouseMap = new HashMap<>();
        warehouseMap.put("corpid", corpid);
        warehouseMap.put("updateTimeEnd", now);
        warehouseMap.put("del", 0);
        warehouseMap.put("pageNum", pageNum);
        warehouseMap.put("orderByStr", "update_time desc");
        while (warehousePageNum > 0 && hasWarehouse) {
            LOG.info("warehousePage:" + warehousePage);
            warehouseMap.put("start", (warehousePage - 1) * pageNum);
            List<WarehouseEntityExt> warehouseList = warehouseModel.findEntitys(warehouseMap);
            for (WarehouseEntityExt warehouse : warehouseList) {
                LOG.info("warehouse.getId():" + warehouse.getId());
                connectorProducerService.triggerSend(corpid, XbbRefTypeEnum.WAREHOUSE, OperateTypeEnum.NEW.getAlias(), warehouse.getId());
            }
            warehousePageNum = warehousePageNum - warehouseList.size();
            hasWarehouse = !warehouseList.isEmpty();
            warehousePage++;
        }


        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        boolQueryBuilder.filter(termQuery(ProductEnum.getEsAttr4Keyword(ProductEnum.PARENT_ID), 0));
        // 更新时间小于当前时间
        boolQueryBuilder.filter(rangeQuery(FieldTypeEnum.UPDATETIME.getAlias()).lt(now));
        List<ProductEntityExt> productList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PRODUCT, boolQueryBuilder, ProductEntityExt.class, Arrays.asList("id"));
        for (ProductEntityExt product : productList) {
            LOG.info("product.getId():" + product.getId());
            connectorProducerService.triggerSend(corpid, XbbRefTypeEnum.PRODUCT, OperateTypeEnum.NEW.getAlias(), product.getId());
        }

        Integer contractPage = 1;
        Integer contractPageNum = totalNum;
        boolean hasContract = true;
        Map<String, Object> contractMap = new HashMap<>();
        contractMap.put("corpid", corpid);
        contractMap.put("endTime", now);
        contractMap.put("del", 0);
        contractMap.put("pageNum", pageNum);
        contractMap.put("orderByStr", "update_time desc");
        while (contractPageNum > 0 && hasContract) {
            LOG.info("contractPage:" + contractPage);
            contractMap.put("start", (contractPage - 1) * pageNum);
            List<ContractEntityExt> contractList = contractModel.findEntitys(contractMap);
            for (ContractEntityExt contract : contractList) {
                LOG.info("contract.getId():" + contract.getId());
                connectorProducerService.triggerSend(corpid, XbbRefTypeEnum.CONTRACT, OperateTypeEnum.NEW.getAlias(), contract.getId());
            }
            contractPageNum = contractPageNum - contractList.size();
            hasContract = !contractList.isEmpty();
            contractPage++;
        }

        Integer paymentPage = 1;
        Integer paymentPageNum = totalNum;
        boolean hasPayment = true;
        Map<String, Object> paymentMap = new HashMap<>();
        paymentMap.put("corpid", corpid);
        paymentMap.put("updateTimeEnd", now);
        paymentMap.put("del", 0);
        paymentMap.put("pageNum", pageNum);
        paymentMap.put("orderByStr", "update_time desc");
        while (paymentPageNum > 0 && hasPayment) {
            LOG.info("paymentPage:" + paymentPage);
            paymentMap.put("start", (paymentPage - 1) * pageNum);
            List<PaymentEntityExt> paymentList = paymentModel.findEntitys(paymentMap);
            for (PaymentEntityExt payment : paymentList) {
                LOG.info("payment.getId():" + payment.getId());
                connectorProducerService.triggerSend(corpid, XbbRefTypeEnum.PAYMENT, OperateTypeEnum.NEW.getAlias(), payment.getId());
            }
            paymentPageNum = paymentPageNum - paymentList.size();
            hasPayment = !paymentList.isEmpty();
            paymentPage++;
        }

        Integer paymentSheetPage = 1;
        Integer paymentSheetPageNum = totalNum;
        boolean hasPaymentSheet = true;
        Map<String, Object> paymentSheetMap = new HashMap<>();
        paymentSheetMap.put("corpid", corpid);
        paymentSheetMap.put("updateTimeEnd", now);
        paymentSheetMap.put("aloneIn", SheetAloneEnum.getNotChildCodeList());
        paymentSheetMap.put("del", 0);
        paymentSheetMap.put("pageNum", pageNum);
        paymentSheetMap.put("orderByStr", "update_time desc");
        while (paymentSheetPageNum > 0 && hasPaymentSheet) {
            LOG.info("paymentSheetPage:" + paymentSheetPage);
            paymentSheetMap.put("start", (paymentSheetPage - 1) * pageNum);
            List<PaymentSheetEntityExt> paymentSheetList = paymentSheetModel.findEntitys(paymentSheetMap);
            for (PaymentSheetEntityExt paymentSheet : paymentSheetList) {
                LOG.info("paymentSheet.getId():" + paymentSheet.getId());
                connectorProducerService.triggerSend(corpid, XbbRefTypeEnum.PAYMENT_SHEET, OperateTypeEnum.NEW.getAlias(), paymentSheet.getId());
            }
            paymentSheetPageNum = paymentSheetPageNum - paymentSheetList.size();
            hasPaymentSheet = !paymentSheetList.isEmpty();
            paymentSheetPage++;
        }

    }

    /**
     * 将从连接器拉取到的数据存库
     * @param corpid 公司id
     * @param list 拉取到的数据列表
     * @throws XbbException
     */
    private void savePaymentSheetList(String corpid, List<PullDataByPageResponseBody.PullDataByPageResponseBodyList> list) throws XbbException {
        if (Objects.isNull(list) || list.isEmpty()) {
            return;
        }
        for (PullDataByPageResponseBody.PullDataByPageResponseBodyList pullData : list) {
            JSONObject jsonData = JSON.parseObject(pullData.getJsonData());
            String operateUserId = jsonData.getString("operateUserId");
            JSONObject data = jsonData.getJSONObject("data");
            PaymentSheetStandardFormatPojo paymentSheetStandardPojo = JSONObject.toJavaObject(data, PaymentSheetStandardFormatPojo.class);
            DdPaymentSheetStandardActionPojo ddPaymentSheetStandardPojo = new DdPaymentSheetStandardActionPojo();
            ddPaymentSheetStandardPojo.setData(paymentSheetStandardPojo);
            ddPaymentSheetStandardPojo.setDdDataAction("add");
            ddPaymentSheetStandardPojo.setDdDataCorpId(corpid);
            ddPaymentSheetStandardPojo.setDdDataCreateAppId(pullData.getDataCreateAppId());
            ddPaymentSheetStandardPojo.setDdDataGmtCreate(pullData.getDataGmtCreate());
            ddPaymentSheetStandardPojo.setDdDataModifiedAppId(pullData.getDataModifiedAppId());
            ddPaymentSheetStandardPojo.setDdDataGmtModified(pullData.getDataGmtModified());
            ddPaymentSheetStandardPojo.setDdDataModelId(DdModelEnum.STANDARD_PAYMENT_SHEET_MODEL.getModelId());
            ddPaymentSheetStandardPojo.setOperateUserId(operateUserId);
            try {
                JSONObject jsonObject = (JSONObject)JSONObject.toJSON(ddPaymentSheetStandardPojo);
                paymentSheetStandardConnector.saveStandard(jsonObject);
            } catch (XbbException e) {
                LOG.error("savePaymentSheetList 异常，" + e.getMessage(), e);
            }

        }
    }

    private void triggersDataSync(String corpid, XbbRefTypeEnum xbbRefTypeEnum, String operate, Long id, String accessToken) throws Exception {
        Config config = new Config();
        config.protocol = "https";
        config.regionId = "central";
        com.aliyun.dingtalkconnector_1_0.Client client = new com.aliyun.dingtalkconnector_1_0.Client(config);
        SyncDataHeaders syncDataHeaders = new SyncDataHeaders();
        syncDataHeaders.xAcsDingtalkAccessToken = accessToken;
        List<SyncDataRequest.SyncDataRequestTriggerDataList> triggerDataList = new ArrayList<>();
        SyncDataRequest.SyncDataRequestTriggerDataList standardDataFormat = triggerStandardMsgDataFormat(corpid, xbbRefTypeEnum, operate, id);
        if (Objects.nonNull(standardDataFormat)) {
            triggerDataList.add(standardDataFormat);
        }
        if (triggerDataList.isEmpty()) {
            return;
        }
        LOG.info("appid:" + ProBaseConfig.getAppId());
        SyncDataRequest syncDataRequest = new SyncDataRequest().setAppId(ProBaseConfig.getAppId())
                .setTriggerDataList(triggerDataList);
        //请求频率处理
        connectorFormatHelper.connectorWait(corpid);
        try {
            LOG.info(xbbRefTypeEnum + ": id: " + id + " " + JSON.toJSONString(triggerDataList));
            client.syncDataWithOptions(syncDataRequest, syncDataHeaders, new RuntimeOptions());
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_PUSH_DATA_TO_CONNECTOR), JSON.toJSONString(standardDataFormat));
            mongoLogHelp.buildLog(corpid, "system", "系统", OperateModuleTypeEnum.CONNECTOR, OperateTypeEnum.PUSH_DATA_CONNECTOR,
                    id.toString(), "连接器", memo, null);
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                LOG.error("operate:" + operate + " id:" + id + "err.code:" + err.code + "err.message:" + err.message);
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                LOG.error("operate:" + operate + " id:" + id + "err.code:" + err.code + "err.message:" + err.message);
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }
        }
    }

    private SyncDataRequest.SyncDataRequestTriggerDataList triggerStandardMsgDataFormat(String corpid, XbbRefTypeEnum xbbRefTypeEnum, String operate, Long id) throws XbbException {
        SyncDataRequest.SyncDataRequestTriggerDataList triggerData = new SyncDataRequest.SyncDataRequestTriggerDataList();

        if (StringUtil.isEmpty(corpid) || Objects.isNull(xbbRefTypeEnum)
                || StringUtil.isEmpty(operate) || Objects.isNull(id) || id < 1L) {
            LOG.error("参数错误，corpid:" + corpid + "xbbRefTypeEnum:" + xbbRefTypeEnum + "operate:" + operate + "id:" + id);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
        }
        switch (operate) {
            case "new":
                operate = "add";
                break;
            case "delete":
                operate = "delete";
                break;
            default:
                operate = "update";
                break;
        }
        String triggerId = DdTriggerEnum.getTriggerId(xbbRefTypeEnum, operate);
        DdStandardFormatPojo ddStandardFormatPojo = null;
        switch (xbbRefTypeEnum) {
            case CUSTOMER:
                ddStandardFormatPojo = customerStandardFormat(corpid, id, operate);
                break;
            case CONTRACT:
                ddStandardFormatPojo = contractStandardFormat(corpid, id, operate);
                break;
            case SALES_OPPORTUNITY:
                ddStandardFormatPojo = opportunityStandardFormat(corpid, id, operate);
                break;
            case PRODUCT:
                ddStandardFormatPojo = productStandardFormat(corpid, id, operate);
                break;
            case PRODUCT_CATEGORY:
                ddStandardFormatPojo = productCategoryStandardFormat(corpid, id);
                break;
            case WAREHOUSE:
                ddStandardFormatPojo = warehouseStandardFormat(corpid, id, operate);
                break;
            case PAYMENT:
                ddStandardFormatPojo = paymentStandardFormat(corpid, id, operate);
                break;
            case PAYMENT_SHEET:
                ddStandardFormatPojo = paymentSheetStandardFormat(corpid, id, operate);
                break;
            default:
                break;
        }

        if (Objects.isNull(ddStandardFormatPojo)) {
            return null;
        }

        if (StringUtil.isEmpty(triggerId)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, "xbbRefTypeEnum错误");
        }
        Long greateTime = ddStandardFormatPojo.getGreateTimeSecond() * 1000L;
        ddStandardFormatPojo.setGreateTimeSecond(null);
        JSONObject json = (JSONObject)JSONObject.toJSON(ddStandardFormatPojo);
        Long modifiedTime = DateTimeUtil.getLong();
        triggerData.setTriggerId(triggerId);
        triggerData.setJsonData(json.toJSONString());
        triggerData.setDataGmtCreate(greateTime);
        triggerData.setDataGmtModified(modifiedTime);
        triggerData.setAction(operate);
        return triggerData;
    }

    /**
     * 客户返回信息格式化(钉钉基本模型)
     * @param corpid
     * @param id
     * @param operate
     * @return
     * @throws XbbException
     */
    private DdStandardFormatPojo customerStandardFormat(String corpid, Long id, String operate) throws XbbException {
        CustomerEntityExt customer = getCustomer(corpid, id, operate);
        if (Objects.isNull(customer)) {
            return null;
        }
        CustomerStandardFormatPojo customerFormatPojo = new CustomerStandardFormatPojo();
        JSONObject customerData = customer.getData();
        String customerName = customerData.getString(CustomerManagementEnum.NAME.getAttr());
        customerFormatPojo.setName(customerName);
        JSONArray customerPhoneArray = customerData.getJSONArray(CustomerManagementEnum.PHONE.getAttr());
        FieldAttrEntity fieldAttr = connectorFormatHelper.getFieldAttr(corpid, customer.getFormId(), CustomerManagementEnum.PHONE.getAttr());
        customerFormatPojo.setPhoneList(connectorFormatHelper.phoneFormat(customerPhoneArray, fieldAttr));
        String serialNo = customer.getSerialNo();
        if (StringUtil.isEmpty(serialNo)) {
            serialNo = BusinessCodePrefixEnum.CUSTOMER_CODE_PREFIX.getPrefix() + customer.getId().toString();
            CustomerEntityExt updateCustomer = new CustomerEntityExt();
            updateCustomer.setCorpid(corpid);
            updateCustomer.setId(id);
            updateCustomer.setSerialNo(serialNo);
            LOG.info("update customer serialNo");
            customerModel.update(updateCustomer);
            customer.setSerialNo(serialNo);
        }
        customerFormatPojo.setCode(serialNo);
        customerFormatPojo.setRemark(customerData.getString(CustomerManagementEnum.MEMO.getAttr()));
        Map<String, String> addressMap = connectorFormatHelper.getAddressMap();
        customerFormatPojo.setAddress(connectorFormatHelper.addressFormat(customerData, CustomerManagementEnum.ADDRESS.getAttr(), addressMap));
        customerFormatPojo.setInvoiceTitleList(connectorFormatHelper.invoiceInfoFormat(corpid, id));
        customerFormatPojo.setCreatorUserId(customerData.getString(CustomerManagementEnum.CREATOR.getAttr()));
        customerFormatPojo.setContactPersonList(connectorFormatHelper.getContactList(corpid, id));

        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);
        param.put("customerId", id);
//        param.put("isMain", 1);
        param.put("del", 0);
        param.put("orderByStr", "add_time desc");
        List<CustomerUserEntity> customerUserList = customerUserModel.findEntitys(param);
        if (!customerUserList.isEmpty()) {
            String empCode = "";
            String empName = "";
            List<String> coworkingEmpCodes = new ArrayList<>();
            for (CustomerUserEntity customerUser : customerUserList) {
                if (Objects.equals(customerUser.getIsMain(), 1) && StringUtil.isEmpty(empCode)) {
                    empCode = customerUser.getUserId();
                    empName = customerUser.getUserName();
                }
                if (Objects.equals(customerUser.getIsMain(), 0)) {
                    String coworkingEmpCode = customerUser.getUserId();
                    coworkingEmpCodes.add(coworkingEmpCode);
                }
            }
            customerFormatPojo.setEmpCode(empCode);
            customerFormatPojo.setEmpName(empName);
            customerFormatPojo.setCoworkingEmpCodes(coworkingEmpCodes);
        }
        List<String> userIdList = customerUserModel.getCustomerUserIdList(corpid, Arrays.asList(customer.getId()), 1);
        if (!userIdList.isEmpty()) {
            customerFormatPojo.setEmpCode(userIdList.get(0));
        }
        DdCustomerStandardFormatPojo ddCustomerFormatPojo = new DdCustomerStandardFormatPojo();
        ddCustomerFormatPojo.setOperateUserId(customer.getCreatorId());
        ddCustomerFormatPojo.setData(customerFormatPojo);
        ddCustomerFormatPojo.setGreateTimeSecond(customer.getAddTime());
        return ddCustomerFormatPojo;
    }

    private CustomerEntityExt getCustomer(String corpid, Long id, String operate) {
        CustomerEntityExt customer;
        if (Objects.equals(operate, "delete")) {
            customer = customerModel.getByKey(id, corpid);
        } else {
            Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.ID, id);
            param.put(ParameterConstant.FLOW_STATUS_IN, Arrays.asList(FlowStatusEnum.PASS.getType(), FlowStatusEnum.NOT_NEED_APPROVAL.getType()));
            List<CustomerEntityExt> customers = customerModel.findEntitysWithoutSub(param);
            customer = CollectionsUtil.isNotEmpty(customers) ? customers.get(0) : null;
        }
        return customer;
    }


    /**
     * 合同返回信息格式化(钉钉基本模型)
     * @param corpid
     * @param id
     * @param operate
     * @return
     * @throws XbbException
     */
    private DdStandardFormatPojo contractStandardFormat(String corpid, Long id, String operate) throws XbbException {
        ContractEntityExt contract = getContract(corpid, id, operate);
        if (Objects.isNull(contract)) {
            return null;
        }
        JSONObject data = contract.getData();
        ContractStandardFormatPojo contractStandardFormatPojo = new ContractStandardFormatPojo();
        contractStandardFormatPojo.setCustomerCode(connectorFormatHelper.getCustomerCode(corpid, data.getLong(ContractEnum.LINK_CUSTOMER.getAttr())));
        contractStandardFormatPojo.setCustomerName(data.getString(ContractEnum.LINK_CUSTOMER_HIDE.getAttr()));
        contractStandardFormatPojo.setCode(contract.getSerialNo());
        contractStandardFormatPojo.setName(data.getString(ContractEnum.NAME.getAttr()));
        contractStandardFormatPojo.setBillDate(data.getLong(ContractEnum.SIGN_TIME.getAttr())*1000L);

        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);
        param.put("contractId", id);
//        param.put("isMain", 1);
        param.put("del", 0);
        param.put("orderByStr", "add_time desc");
        List<ContractUserEntity> contractUserList = contractUserModel.findEntitys(param);
        if (!contractUserList.isEmpty()) {
            String empCode = "";
            String empName = "";
            List<String> coworkingEmpCodes = new ArrayList<>();
            for (ContractUserEntity contractUser : contractUserList) {
                if (Objects.equals(contractUser.getIsMain(), 1) && StringUtil.isEmpty(empCode)) {
                    empCode = contractUser.getUserId();
                    empName = contractUser.getUserName();
                }
                if (Objects.equals(contractUser.getIsMain(), 0)) {
                    String coworkingEmpCode = contractUser.getUserId();
                    coworkingEmpCodes.add(coworkingEmpCode);
                }
            }
            contractStandardFormatPojo.setEmpCode(empCode);
            contractStandardFormatPojo.setEmpName(empName);
            contractStandardFormatPojo.setCoworkingEmpCodes(coworkingEmpCodes);
        }

//        contractCommonFormatPojo.setAttachmentList();
        Long deadline = data.getLong(ContractEnum.DEADLINE.getAttr());
        if (Objects.nonNull(deadline)) {
            contractStandardFormatPojo.setDeadline(deadline*1000L);
        }
        contractStandardFormatPojo.setAmount(data.getDouble(ContractEnum.AMOUNT.getAttr()).toString());
        String statusText = dataDictionaryModel.getDictionaryValue(corpid, DictionaryEnum.CONTRACT_STATUS, data.getString(ContractEnum.STATUS.getAttr()));
        contractStandardFormatPojo.setStatus(statusText);
        String signPersonId = data.getString(ContractEnum.SIGN_PERSON.getAttr());
        UserEntity user = userModel.getByKey(signPersonId, corpid);
        if (Objects.nonNull(user)) {
            contractStandardFormatPojo.setSignPersonId(signPersonId);
            contractStandardFormatPojo.setSignPersonName(user.getName());
        }

        List<ProductStandardPojo> productList = getMaterialList(corpid, id);
        contractStandardFormatPojo.setProductList(productList);

        DdContractStandardFormatPojo ddContractStandardFormatPojo = new DdContractStandardFormatPojo();
        ddContractStandardFormatPojo.setOperateUserId(contract.getCreatorId());
        ddContractStandardFormatPojo.setData(contractStandardFormatPojo);
        ddContractStandardFormatPojo.setGreateTimeSecond(contract.getAddTime());
        return ddContractStandardFormatPojo;
    }

    private ContractEntityExt getContract(String corpid, Long id, String operate) {
        ContractEntityExt contract;
        if (Objects.equals(operate, "delete")) {
            contract = contractModel.getByKey(id, corpid);
        } else {
            Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.ID, id);
            param.put(ParameterConstant.FLOW_STATUS_IN, Arrays.asList(FlowStatusEnum.PASS.getType(), FlowStatusEnum.NOT_NEED_APPROVAL.getType()));
            List<ContractEntityExt> contracts = contractModel.findEntitysWithoutSub(param);
            contract = CollectionsUtil.isNotEmpty(contracts) ? contracts.get(0) : null;
        }
        return contract;
    }

    /**
     * 销售机会返回信息格式化(钉钉基本模型)
     * @param corpid
     * @param id
     * @param operate
     * @return
     * @throws XbbException
     */
    private DdStandardFormatPojo opportunityStandardFormat(String corpid, Long id, String operate) throws XbbException {
        OpportunityEntityExt opportunity = getOpportunity(corpid, id, operate);
        if (Objects.isNull(opportunity)) {
            return null;
        }
        JSONObject data = opportunity.getData();
        OpportunityStandardFormatPojo salesOpportunityStandardFormatPojo = new OpportunityStandardFormatPojo();
        salesOpportunityStandardFormatPojo.setCode(opportunity.getSerialNo());
        salesOpportunityStandardFormatPojo.setName(data.getString(SalesOpportunityEnum.NAME.getAttr()));
        salesOpportunityStandardFormatPojo.setRelatedCustomerId(connectorFormatHelper.getCustomerCode(corpid, data.getLong(SalesOpportunityEnum.CUSTOMER_NAME.getAttr())));
        salesOpportunityStandardFormatPojo.setContactPersonId(connectorFormatHelper.getContactCode(corpid, data.getLong(SalesOpportunityEnum.CONTACT_NAME.getAttr())));
        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);
        param.put("opportunityId", id);
        param.put("del", 0);
        param.put("orderByStr", "add_time desc");
        List<OpportunityUserEntity> opportunityUserList = opportunityUserModel.findEntitys(param);
        if (!opportunityUserList.isEmpty()) {
            String empCode = "";
            String empName = "";
            List<String> coworkingEmpCodes = new ArrayList<>();
            for (OpportunityUserEntity opportunityUser : opportunityUserList) {
                if (Objects.equals(opportunityUser.getIsMain(), 1) && StringUtil.isEmpty(empCode)) {
                    empCode = opportunityUser.getUserId();
                    empName = opportunityUser.getUserName();
                }
                if (Objects.equals(opportunityUser.getIsMain(), 0)) {
                    String coworkingEmpCode = opportunityUser.getUserId();
                    coworkingEmpCodes.add(coworkingEmpCode);
                }
            }
            salesOpportunityStandardFormatPojo.setOwnerEmpCode(empCode);
//            salesOpportunityStandardFormatPojo.setEmpName(empName);
            salesOpportunityStandardFormatPojo.setCoworkingEmpCodes(coworkingEmpCodes);
        }
        salesOpportunityStandardFormatPojo.setExpectedAmount(data.getDouble(SalesOpportunityEnum.ESTIMATE_AMOUNT.getAttr()).toString());
        Long estimateEndTime = data.getLong(SalesOpportunityEnum.ESTIMATE_END_TIME.getAttr());
        if (Objects.nonNull(estimateEndTime)) {
            salesOpportunityStandardFormatPojo.setExpectedExpiredAt(estimateEndTime * 1000L);
        }
        salesOpportunityStandardFormatPojo.setCreatorCode(opportunity.getCreatorId());
        DdOpportunityStandardFormatPojo ddOpportunityStandardFormatPojo = new DdOpportunityStandardFormatPojo();
        ddOpportunityStandardFormatPojo.setOperateUserId(opportunity.getCreatorId());
        ddOpportunityStandardFormatPojo.setData(salesOpportunityStandardFormatPojo);
        ddOpportunityStandardFormatPojo.setGreateTimeSecond(opportunity.getAddTime());
        return ddOpportunityStandardFormatPojo;
    }


    private OpportunityEntityExt getOpportunity(String corpid, Long id, String operate) {
        OpportunityEntityExt opportunity;
        if (Objects.equals(operate, "delete")) {
            opportunity = opportunityModel.getByKey(id, corpid);
        } else {
            Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.ID, id);
            param.put(ParameterConstant.FLOW_STATUS_IN, Arrays.asList(FlowStatusEnum.PASS.getType(), FlowStatusEnum.NOT_NEED_APPROVAL.getType()));
            List<OpportunityEntityExt> opportunitys = opportunityModel.findEntitysWithoutSub(param);
            opportunity = CollectionsUtil.isNotEmpty(opportunitys) ? opportunitys.get(0) : null;
        }
        return opportunity;
    }

    private List<ProductStandardPojo> getMaterialList(String corpid, Long contractId) throws XbbException {
        BoolQueryBuilder contractProductBoolQueryBuilder = boolQuery();
        contractProductBoolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        contractProductBoolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        contractProductBoolQueryBuilder.filter(termQuery(ContractProductSubFormEnum.getEsAttr(ContractProductSubFormEnum.TYPE), 201));
        contractProductBoolQueryBuilder.filter(termQuery(ContractProductSubFormEnum.getEsAttr(ContractProductSubFormEnum.CONTRACT_ID), contractId));
        contractProductBoolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_CONTRACT_PRODUCT.getType()));
        List<String> contractProductFieldList = Arrays.asList(ContractProductSubFormEnum.getAttrConnectData(ContractProductSubFormEnum.CONTRACT_ID),
                ContractProductSubFormEnum.getAttrConnectData(ContractProductSubFormEnum.PRODUCT_ID),
                ContractProductSubFormEnum.getAttrConnectData(ContractProductSubFormEnum.PARENT_ID),
                ContractProductSubFormEnum.getAttrConnectData(ContractProductSubFormEnum.DISCOUNT),
                ContractProductSubFormEnum.getAttrConnectData(ContractProductSubFormEnum.PRODUCT_NAME),
                ContractProductSubFormEnum.getAttrConnectData(ContractProductSubFormEnum.SPECIFICATION),
                ContractProductSubFormEnum.getAttrConnectData(ContractProductSubFormEnum.PRODUCT_NUM),
                ContractProductSubFormEnum.getAttrConnectData(ContractProductSubFormEnum.PRICE),
                ContractProductSubFormEnum.getAttrConnectData(ContractProductSubFormEnum.SUM_PRICE),
                ContractProductSubFormEnum.getAttrConnectData(ContractProductSubFormEnum.PRODUCT_UNIT),
                ContractProductSubFormEnum.getAttrConnectData(ContractProductSubFormEnum.MEMO));
        List<PaasFormDataEntity> contractProductList =  esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CONTRACT_PRODUCT, contractProductBoolQueryBuilder, PaasFormDataEntity.class, contractProductFieldList);
        List<ContractProductEntity> contractProductEntities = transferSubFormHelper.transferFormDataToContractProductList(contractProductList);

        Set<Long> productIdSet = new HashSet<>();
        for (ContractProductEntity contractProduct : contractProductEntities) {
            Long productId = contractProduct.getProductId();
            Long parentId = contractProduct.getParentId();
            if (Objects.nonNull(productId) && productId > 0L) {
                productIdSet.add(productId);
            }
            if (Objects.nonNull(parentId) && parentId > 0L) {
                productIdSet.add(parentId);
            }
        }
        Map<Long,ProductEntityExt> productMap = productModel.getProductMapByIdIn(corpid, new ArrayList<>(productIdSet), 0);
        Map<String, String> unitMap = getUnitMap4LinkProduct(corpid);
        List<ProductStandardPojo> materialList = new ArrayList<>();
        for (ContractProductEntity contractProductEntity : contractProductEntities) {
            String productName = contractProductEntity.getProductName();
//            Double discount = contractProductEntity.getDiscount()/100;
            Double productNum = contractProductEntity.getProductNum();
            Double productPrice = contractProductEntity.getPrice();
            Double productTotalPrice = Math.abs(contractProductEntity.getProductNum() * contractProductEntity.getPrice());
            String productMemo = contractProductEntity.getMemo();

            String productUnit = contractProductEntity.getProductUnit();

            ProductStandardPojo materialStandardPojo = new ProductStandardPojo();

            Long parentId = contractProductEntity.getParentId();
            ProductEntityExt parentProduct = productMap.get(parentId);
            JSONObject parentProductData = parentProduct.getData();
            materialStandardPojo.setName(productName);
            materialStandardPojo.setProductCode(parentProductData.getString(ProductEnum.PRODUCT_NO.getAttr()));
            String unitNumber = null;
            if (unitMap.containsKey(productUnit)) {
                unitNumber = unitMap.get(productUnit);
            } else {
                unitNumber = productUnit;
            }

            Long productId = contractProductEntity.getProductId();
            ProductEntityExt product = productMap.get(productId);
            JSONObject productData = product.getData();
            materialStandardPojo.setSkuCode(productData.getString(ProductEnum.PRODUCT_NO.getAttr()));
//            Double price = productData.getDouble(ProductEnum.PRICE.getAttr());
            materialStandardPojo.setComment(productMemo);
            materialStandardPojo.setAmount(productTotalPrice.toString());
//            materialStandardPojo.setDiscountRate(discount.toString());
            materialStandardPojo.setTaxPrice(productPrice.toString());
            materialStandardPojo.setRemark(productMemo);
            materialStandardPojo.setQuantity(productNum.toString());
            materialStandardPojo.setPrice(productPrice.toString());
            materialStandardPojo.setUnitCode(unitNumber);
            materialList.add(materialStandardPojo);
        }
        return materialList;
    }


    /**
     * 产品返回信息格式化(钉钉基本模型)
     * @param corpid
     * @param id
     * @param operate
     * @return
     * @throws XbbException
     */
    private DdStandardFormatPojo productStandardFormat(String corpid, Long id, String operate) throws XbbException {
        ProductEntityExt product = getProduct(corpid, id, operate);
        if (Objects.isNull(product)) {
            return null;
        }
        LOG.info("product:"+ product);
        ProductStandardFormatPojo productFormatPojo = new ProductStandardFormatPojo();
        JSONObject productData = product.getData();
        productFormatPojo.setName(productData.getString(ProductEnum.NAME.getAttr()));
        productFormatPojo.setCode(productData.getString(ProductEnum.PRODUCT_NO.getAttr()));
        Long categoryId = productData.getLong(ProductEnum.CATEGORY_ID.getAttr());
        if (Objects.nonNull(categoryId)) {
            productFormatPojo.setProductCategoryCode(connectorFormatHelper.getCategoryCode(corpid, categoryId));
        }
        productFormatPojo.setBarcode(productData.getString(ProductEnum.BARCODE.getAttr()));
        Integer enableMultiUnit = productData.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr());
        Long groupId = 0L;
        if (Objects.equals(enableMultiUnit, BasicConstant.IS_USE)) {
            groupId = productData.getLong(ProductEnum.UNIT.getAttr());
        }
        Map<String, String> unitMap = getUnitMap4Product(corpid, groupId);
        String unitId = productData.getString(ProductEnum.UNIT.getAttr());
        if (unitMap.containsKey(unitId)) {
            productFormatPojo.setBaseUnitCode(unitMap.get(unitId));
        } else {
            productFormatPojo.setBaseUnitCode(unitId);
        }
        BoolQueryBuilder skuBoolQueryBuilder = boolQuery();
        skuBoolQueryBuilder.filter(termQuery("corpid.keyword",corpid));
        skuBoolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        skuBoolQueryBuilder.filter(termQuery(ProductEnum.getEsAttr4Keyword(ProductEnum.PARENT_ID), product.getId()));
        skuBoolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_PRODUCT.getType()));
        List<String> skuFieldList = Arrays.asList(ProductEnum.getAttrConnectData(ProductEnum.PRODUCT_NO),
                ProductEnum.getAttrConnectData(ProductEnum.SPECIFICATION_LINK_TEXT),
                ProductEnum.getAttrConnectData(ProductEnum.COST),
                ProductEnum.getAttrConnectData(ProductEnum.PRICE));
        List<PaasFormDataEntity> skuList =  esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PRODUCT, skuBoolQueryBuilder, PaasFormDataEntity.class, skuFieldList);
        List<ModelStandardPojo> modelList = new ArrayList<>();
        for (PaasFormDataEntity skuEntity : skuList) {
            JSONObject skuData = skuEntity.getData();
            ModelStandardPojo modelStandardPojo = new ModelStandardPojo();
            modelStandardPojo.setSkuCode(skuData.getString(ProductEnum.PRODUCT_NO.getAttr()));
            String specificationStr = skuData.getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr());
            List<AttributeStandardPojo> attributeList = getAttributeList(specificationStr);
            if (Objects.nonNull(attributeList)) {
                modelStandardPojo.setAttributeList(attributeList);
            } else {
                modelStandardPojo.setSkuDescription(specificationStr);
            }
            modelList.add(modelStandardPojo);
        }
        productFormatPojo.setModelList(modelList);
        List<PriceStandardPojo> priceList = getPriceList(skuList, productFormatPojo.getBaseUnitCode());
        productFormatPojo.setPriceList(priceList);
        DdProductStandardFormatPojo ddProductStandardFormatPojo = new DdProductStandardFormatPojo();
        ddProductStandardFormatPojo.setData(productFormatPojo);
        ddProductStandardFormatPojo.setOperateUserId(product.getCreatorId());
        ddProductStandardFormatPojo.setGreateTimeSecond(product.getAddTime());
        return ddProductStandardFormatPojo;
    }

    private ProductEntityExt getProduct(String corpid, Long id, String operate) {
        ProductEntityExt product;
        if (Objects.equals(operate, "delete")) {
            product = productModel.getByKey(id, corpid);
        } else {
            Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.ID, id);
            param.put(ParameterConstant.FLOW_STATUS_IN, Arrays.asList(FlowStatusEnum.PASS.getType(), FlowStatusEnum.NOT_NEED_APPROVAL.getType()));
            param.put("dataParentId", 0);
            List<ProductEntityExt> products = productModel.findEntitysWithoutSub(param);
            product = CollectionsUtil.isNotEmpty(products) ? products.get(0) : null;
        }
        return product;
    }

    /**
     * 1、单单位价格
     * 2、多单位价格，现在通过基础单位将多单位转化成单单位价格
     * @param skuList
     * @param baseUnitNumber
     * @return
     */
    private List<PriceStandardPojo> getPriceList(List<PaasFormDataEntity> skuList, String baseUnitNumber) {
        List<PriceStandardPojo> priceList = new ArrayList<>();
        for (PaasFormDataEntity skuEntity : skuList) {
            JSONObject skuData = skuEntity.getData();
            PriceStandardPojo priceStandardPojo = new PriceStandardPojo();
            priceStandardPojo.setSkuCode(skuData.getString(ProductEnum.PRODUCT_NO.getAttr()));
            priceStandardPojo.setCostPrice(skuData.getDouble(ProductEnum.COST.getAttr()).toString());
            priceStandardPojo.setRetailPrice(skuData.getDouble(ProductEnum.PRICE.getAttr()).toString());
            priceStandardPojo.setUnitCode(baseUnitNumber);
            priceList.add(priceStandardPojo);
        }
        return priceList;
    }

    /**
     * null或者""或者单规格或者类型转化失败时返回null
     * 多规格 {"颜色":"白色","尺寸":"M"}
     * @param specificationStr
     * @return
     */
    private List<AttributeStandardPojo> getAttributeList(String specificationStr) {
        if (StringUtil.isEmpty(specificationStr)) {
            return null;
        }
        JSONObject specificationJson = null;
        try {
            specificationJson = JSON.parseObject(specificationStr);
        } catch (Exception e) {

        }

        if (Objects.isNull(specificationJson)) {
            return null;
        }
        List<AttributeStandardPojo> attributeList = new ArrayList<>();
        Set<String> keySet = specificationJson.keySet();
        for (String attributeName : keySet) {
            String value = specificationJson.getString(attributeName);
            AttributeStandardPojo attributeStandardPojo = new AttributeStandardPojo();
            attributeStandardPojo.setAttributeName(attributeName);
            attributeStandardPojo.setValue(value);
            attributeList.add(attributeStandardPojo);
        }
        return attributeList;
    }


    /**
     * 产品分类返回信息格式化(钉钉基本模型)
     * @param corpid
     * @param id
     * @return
     * @throws XbbException
     */
    private DdStandardFormatPojo productCategoryStandardFormat(String corpid, Long id) throws XbbException {
        ProductCategoryStandardFormatPojo productCategoryFormatPojo = new ProductCategoryStandardFormatPojo();
        ProductCategoryEntity productCategory = productCategoryModel.getByKey(id, corpid);
        if (Objects.isNull(productCategory)) {
            return null;
        }
        String serialNo = productCategory.getSerialNo();
        if (StringUtil.isEmpty(serialNo)) {
            serialNo = BusinessCodePrefixEnum.PRODUCT_CATEGORY_CODE_PREFIX.getPrefix() + productCategory.getId().toString();
            updateSerialNo(productCategory, serialNo);
        }
        productCategoryFormatPojo.setCode(serialNo);

        productCategoryFormatPojo.setName(productCategory.getName());
        Long parentId = productCategory.getParentId();
        if (Objects.nonNull(parentId) && parentId > 0L) {
            ProductCategoryEntity parentProductCategory = productCategoryModel.getByKey(parentId, corpid);
            String parentSerialNo = parentProductCategory.getSerialNo();
            if (StringUtil.isEmpty(parentSerialNo)) {
                parentSerialNo = BusinessCodePrefixEnum.PRODUCT_CATEGORY_CODE_PREFIX.getPrefix() + parentId.toString();
                updateSerialNo(parentProductCategory, parentSerialNo);
            }
            productCategoryFormatPojo.setParentCode(parentSerialNo);
        }
        DdProductCategoryStandardFormatPojo ddProductCategoryStandardFormatPojo = new DdProductCategoryStandardFormatPojo();
        ddProductCategoryStandardFormatPojo.setOperateUserId(productCategory.getCreatorId());
        ddProductCategoryStandardFormatPojo.setData(productCategoryFormatPojo);
        ddProductCategoryStandardFormatPojo.setGreateTimeSecond(productCategory.getAddTime());
        return ddProductCategoryStandardFormatPojo;
    }

    private void updateSerialNo(ProductCategoryEntity productCategory, String serialNo) throws XbbException {
        if (Objects.isNull(productCategory) || Objects.isNull(productCategory.getId())) {
            LOG.error("updateSerialNo error,productCategory:" + JSON.toJSONString(productCategory));
        }
        LOG.info("update productCategory serialNo,id:" + productCategory.getId() + " serialNo:" + serialNo);
        productCategory.setSerialNo(serialNo);
        productCategoryModel.update(productCategory);
    }


    /**
     * 仓库返回信息格式化(钉钉基本模型)
     * @param corpid
     * @param id
     * @param operate
     * @return
     * @throws XbbException
     */
    private DdStandardFormatPojo warehouseStandardFormat(String corpid, Long id, String operate) throws XbbException {
        WarehouseStandardFormatPojo warehouseFormatPojo = new WarehouseStandardFormatPojo();
        WarehouseEntityExt warehouse = getWarehouse(corpid, id, operate);
        if (Objects.isNull(warehouse)) {
            return null;
        }
        String serialNo = warehouse.getSerialNo();
        JSONObject data = warehouse.getData();
        warehouseFormatPojo.setCode(serialNo);
        warehouseFormatPojo.setName(data.getString(WarehouseEnum.WAREHOUSE_NAME.getAttr()));
        warehouseFormatPojo.setRemark(data.getString(WarehouseEnum.MEMO.getAttr()));
        DdWarehouseStandardFormatPojo ddWarehouseStandardFormatPojo = new DdWarehouseStandardFormatPojo();
        ddWarehouseStandardFormatPojo.setOperateUserId(warehouse.getCreatorId());
        ddWarehouseStandardFormatPojo.setData(warehouseFormatPojo);
        ddWarehouseStandardFormatPojo.setGreateTimeSecond(warehouse.getAddTime());
        return ddWarehouseStandardFormatPojo;
    }

    private WarehouseEntityExt getWarehouse(String corpid, Long id, String operate) {
        WarehouseEntityExt warehouse;
        if (Objects.equals(operate, "delete")) {
            warehouse = warehouseModel.getByKey(id, corpid);
        } else {
            Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.ID, id);
            param.put(ParameterConstant.FLOW_STATUS_IN, Arrays.asList(FlowStatusEnum.PASS.getType(), FlowStatusEnum.NOT_NEED_APPROVAL.getType()));
            List<WarehouseEntityExt> warehouses = warehouseModel.findEntitysWithoutSub(param);
            warehouse = CollectionsUtil.isNotEmpty(warehouses) ? warehouses.get(0) : null;
        }
        return warehouse;
    }

    /**
     * 回款计划返回信息格式化(钉钉基本模型)
     * @param corpid
     * @param id
     * @param operate
     * @return
     */
    private DdStandardFormatPojo paymentStandardFormat(String corpid, Long id, String operate) throws XbbException {
        PaymentStandardFormatPojo paymentStandardFormatPojo = new PaymentStandardFormatPojo();
        PaymentEntityExt payment = getPayment(corpid, id, operate);
        if (Objects.isNull(payment)) {
            return null;
        }
        Map<String, Object> paymentUserMap = new HashMap<>();
        paymentUserMap.put("corpid", corpid);
        paymentUserMap.put("dataId", id);
        paymentUserMap.put("isMain", 1);
        paymentUserMap.put("del", 0);
        paymentUserMap.put("pageSize", 1);
        List<UserTeamEntity> paymentUserList = paymentUserModel.findBaseEntitys(paymentUserMap);
        String ownerId = paymentUserList.isEmpty() ? null : paymentUserList.get(0).getUserId();
        String serialNo = payment.getSerialNo();
        String creatorId = payment.getCreatorId();
        JSONObject data = payment.getData();
        paymentStandardFormatPojo.setCode(serialNo);

        String status = data.getString(PaymentEnum.STATUS.getAttr());
        List<PaymentStatusEnum> incomeEnums = Arrays.asList(PaymentStatusEnum.UN_RECEIVABLES,
                PaymentStatusEnum.RECEIVABLES, PaymentStatusEnum.PARTIAL_RECEIPTS);
        List<PaymentStatusEnum> redEnums = Arrays.asList(PaymentStatusEnum.RED_RECEIVABLES);

        PaymentStatusEnum paymentStatusEnum = PaymentStatusEnum.getByCode(status);
        boolean isReverse = false;
        if (incomeEnums.contains(paymentStatusEnum)) {
            isReverse = false;
        }
        if (redEnums.contains(paymentStatusEnum)) {
            isReverse = true;
            Long originId = data.getLong(PaymentEnum.RECEIVABLES_ORIGIN_ID.getAttr());
            String fromStmtCode = getPaymentCodeById(corpid, originId);
            paymentStandardFormatPojo.setFromStmtCode(fromStmtCode);
        }
        paymentStandardFormatPojo.setReverse(isReverse);
        Double amount = data.getDouble(PaymentEnum.AMOUNT.getAttr());
        Double realAmount = data.getDouble(PaymentEnum.REAL_AMOUNT.getAttr());
        Double balAmount = amount - realAmount;
        paymentStandardFormatPojo.setAmount(amount.toString());
        paymentStandardFormatPojo.setPaidAmount(realAmount.toString());
        paymentStandardFormatPojo.setBalAmount(balAmount.toString());
        paymentStandardFormatPojo.setOffsetAmount("0.0");
        paymentStandardFormatPojo.setCancelAmount("0.0");
        Long estimateTime = data.getLong(PaymentEnum.ESTIMATE_TIME.getAttr());
        Long dueDate = estimateTime * 1000L;
        paymentStandardFormatPojo.setDueDate(dueDate);
        Long addTime = payment.getAddTime();
        Long billDate = addTime * 1000L;
        paymentStandardFormatPojo.setBillDate(billDate);
        paymentStandardFormatPojo.setIncludeTax("1");
        Long contractId = data.getLong(PaymentEnum.CONTRACT.getAttr());
        ContractEntityExt contract = contractModel.getByKey(contractId, corpid);
        if (Objects.nonNull(contract)) {
            paymentStandardFormatPojo.setOrderCode(contract.getSerialNo());
        }
        paymentStandardFormatPojo.setRemark(data.getString(PaymentEnum.MEMO.getAttr()));
        paymentStandardFormatPojo.setCreatorCode(creatorId);
        List<String> userIds = new ArrayList<>();
        if (StringUtil.isNotEmpty(ownerId)) {
            userIds.add(ownerId);
        }
        userIds.add(payment.getCreatorId());
        Map<String, String> userIdNameMap = userModel.getUserIdNameMap(corpid, userIds);
        if (StringUtil.isNotEmpty(ownerId)) {
            paymentStandardFormatPojo.setEmpCode(ownerId);
            paymentStandardFormatPojo.setEmpName(userIdNameMap.get(ownerId));
        }
        paymentStandardFormatPojo.setCreatorName(userIdNameMap.get(creatorId));
        DdPaymentStandardFormatPojo ddPaymentStandardFormatPojo = new DdPaymentStandardFormatPojo();
        ddPaymentStandardFormatPojo.setOperateUserId(creatorId);
        ddPaymentStandardFormatPojo.setData(paymentStandardFormatPojo);
        ddPaymentStandardFormatPojo.setGreateTimeSecond(addTime);
        return ddPaymentStandardFormatPojo;
    }

    private PaymentEntityExt getPayment(String corpid, Long id, String operate) {
        PaymentEntityExt payment;
        if (Objects.equals(operate, "delete")) {
            payment = paymentModel.getByKey(id, corpid);
        } else {
            Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.ID, id);
            param.put(ParameterConstant.FLOW_STATUS_IN, Arrays.asList(FlowStatusEnum.PASS.getType(), FlowStatusEnum.NOT_NEED_APPROVAL.getType()));
            List<PaymentEntityExt> payments = paymentModel.findEntitysWithoutSub(param);
            payment = CollectionsUtil.isNotEmpty(payments) ? payments.get(0) : null;
        }
        return payment;
    }

    private String getPaymentCodeById(String corpid, Long id) {
        PaymentEntityExt payment = paymentModel.getByKey(id, corpid);
        if (Objects.isNull(payment)) {
            return null;
        }
        return payment.getSerialNo();
    }


    /**
     * 回款单返回信息格式化(钉钉基本模型)
     * @param corpid
     * @param id
     * @param operate
     * @return
     * @throws XbbException
     */
    private DdStandardFormatPojo paymentSheetStandardFormat(String corpid, Long id, String operate) throws XbbException {
        PaymentSheetStandardFormatPojo paymentSheetStandardFormatPojo = new PaymentSheetStandardFormatPojo();
        PaymentSheetEntityExt paymentSheet = getPaymentSheet(corpid, id, operate);
        if (Objects.isNull(paymentSheet)) {
            return null;
        }

        if (Objects.equals(paymentSheet.getAlone(), SheetAloneEnum.CHILD.getCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404, "子回款单不同步");
        }

        String serialNo = paymentSheet.getSerialNo();
        JSONObject data = paymentSheet.getData();
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(paymentSheet.getFormId(), corpid);
        List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
        Map<String, FieldAttrEntity> explainMap = new HashMap<>();
        explainList.forEach(item -> {
            explainMap.put(item.getAttr(), item);
        });
        paymentSheetStandardFormatPojo.setCode(serialNo);
        Integer recvType = 1;
        String fromRecvCode = null;
        String type = data.getString(PaymentSheetEnum.PAYMENT_SHEET_TYPE.getAttr());
        if (PaymentSheetTypeEnum.isWriteOff(type)) {
            recvType = 1;
        } else if (PaymentSheetTypeEnum.isRed(type)) {
            recvType = 2;
            Long originSheetId = data.getLong(PaymentSheetEnum.RED_SHEET.getAttr());
            fromRecvCode = getPaymentSheetCodeById(corpid, originSheetId);
        } else if (PaymentSheetTypeEnum.isBad(type)) {
            recvType = 3;
        } else {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018, "回款单其他回款单不同步到连接器");
        }
        paymentSheetStandardFormatPojo.setRecvType(recvType);
        paymentSheetStandardFormatPojo.setFromRecvCode(fromRecvCode);
        Long customerId = data.getLong(PaymentSheetEnum.CUSTOMER_ID.getAttr());
        CustomerEntityExt customer = customerModel.getByKey(customerId, corpid);
        if (Objects.nonNull(customer)) {
            JSONObject customerData = customer.getData();
            paymentSheetStandardFormatPojo.setCustomerCode(connectorFormatHelper.getCustomerCode(customer));
            paymentSheetStandardFormatPojo.setCustomerName(customerData.getString(CustomerManagementEnum.NAME.getAttr()));
        }
        JSONArray belongIdArray = data.getJSONArray(PaymentSheetEnum.BELONG_ID.getAttr());
        if (Objects.nonNull(belongIdArray) && !belongIdArray.isEmpty()) {
            List<String> belongIdList = belongIdArray.toJavaList(String.class);
            String empCode = belongIdList.get(0);
            Map<String, String> userIdNameMap = userModel.getUserIdNameMap(corpid, Arrays.asList(empCode));
            paymentSheetStandardFormatPojo.setEmpCode(empCode);
            paymentSheetStandardFormatPojo.setEmpName(userIdNameMap.get(empCode));
        }
        Long date = data.getLong(PaymentSheetEnum.PAYMENT_TIME.getAttr());
        paymentSheetStandardFormatPojo.setBillDate(date * 1000L);
        List<ItemPoJo> itemPoJoList = proFormHelp.handleFundAccountItems(corpid, XbbRefTypeEnum.PAYMENT_SHEET.getCode());
        String fundAccountCode = data.getString(PaymentSheetEnum.FUND_ACCOUNT.getAttr());
        paymentSheetStandardFormatPojo.setSettleAccount(getComboText(itemPoJoList, fundAccountCode));
        String payMethodCode = data.getString(PaymentSheetEnum.PAY_METHOD.getAttr());
        paymentSheetStandardFormatPojo.setPayType(getComboText(explainMap.get(PaymentSheetEnum.PAY_METHOD.getAttr()), payMethodCode));
        Double amount = data.getDouble(PaymentSheetEnum.AMOUNT.getAttr());
        amount = Objects.isNull(amount) ? 0D : amount;
        paymentSheetStandardFormatPojo.setAmount(amount.toString());
        paymentSheetStandardFormatPojo.setRemark(data.getString(PaymentSheetEnum.MEMO.getAttr()));
        List<PaymentEntityExt> paymentList = null;
        JSONArray paymentIdArray = data.getJSONArray(PaymentSheetEnum.PAYMENT.getAttr());
        if (Objects.nonNull(paymentIdArray) && !paymentIdArray.isEmpty()) {
            Map<String, Object> paymenParam = new HashMap<>();
            paymenParam.put("corpid", corpid);
            paymenParam.put("idIn", paymentIdArray);
            paymenParam.put("del", 0);
            paymentList = paymentModel.findEntitysWithoutSub(paymenParam);
        }
        List<ContractEntityExt> contractList = null;
        JSONArray contractIdArray = data.getJSONArray(PaymentSheetEnum.CONTRACT.getAttr());
        if (Objects.nonNull(contractIdArray) && !contractIdArray.isEmpty()) {
            Map<String, Object> contractParam = new HashMap<>();
            contractParam.put("corpid", corpid);
            contractParam.put("idIn", contractIdArray);
            contractParam.put("del", 0);
            contractList = contractModel.findEntitysWithoutSub(contractParam);
        }
        setStmtAndOrder(corpid, paymentSheetStandardFormatPojo, contractList, paymentList, amount, paymentSheet.getAlone(), paymentSheet.getUuid());
        DdPaymentSheetStandardFormatPojo ddPaymentSheetStandardFormatPojo = new DdPaymentSheetStandardFormatPojo();
        ddPaymentSheetStandardFormatPojo.setOperateUserId(paymentSheet.getCreatorId());
        ddPaymentSheetStandardFormatPojo.setData(paymentSheetStandardFormatPojo);
        ddPaymentSheetStandardFormatPojo.setGreateTimeSecond(paymentSheet.getAddTime());
        return ddPaymentSheetStandardFormatPojo;
    }

    private PaymentSheetEntityExt getPaymentSheet(String corpid, Long id, String operate) {
        PaymentSheetEntityExt paymentSheet;
        if (Objects.equals(operate, "delete")) {
            paymentSheet = paymentSheetModel.getByKey(id, corpid);
        } else {
            Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.ID, id);
            param.put(ParameterConstant.FLOW_STATUS_IN, Arrays.asList(FlowStatusEnum.PASS.getType(), FlowStatusEnum.NOT_NEED_APPROVAL.getType()));
            param.put("aloneIn", SheetAloneEnum.getNotChildCodeList());
            List<PaymentSheetEntityExt> paymentSheets = paymentSheetModel.findEntitysWithoutSub(param);
            paymentSheet = CollectionsUtil.isNotEmpty(paymentSheets) ? paymentSheets.get(0) : null;
        }
        return paymentSheet;
    }

    private String getPaymentSheetCodeById(String corpid, Long id) {
        PaymentSheetEntityExt paymentSheet = paymentSheetModel.getByKey(id, corpid);
        if (Objects.isNull(paymentSheet)) {
            return null;
        }
        return paymentSheet.getSerialNo();
    }

    /**
     * 通过选项值获取选项文本
     * @param fieldAttr
     * @param value
     * @return
     * 创建时间 2021/7/8 4:14 PM
     * 修改时间 2021/7/8 4:14 PM
     * @author chy
     */
    private String getComboText(FieldAttrEntity fieldAttr, String value) {
        List<ItemPoJo> itemPoJoList = fieldAttr.getItems();
        return getComboText(itemPoJoList, value);
    }

    /**
     * 通过选项值获取选项文本
     * @param itemPoJoList
     * @param value
     * @return
     * 创建时间 2021/7/8 4:14 PM
     * 修改时间 2021/7/8 4:14 PM
     * @author chy
     */
    private String getComboText(List<ItemPoJo> itemPoJoList, String value) {
        if (StringUtil.isEmpty(value)) {
            return null;
        }
        String text = null;
        for (ItemPoJo itemPoJo : itemPoJoList) {
            if (Objects.equals(itemPoJo.getValue(), value)) {
                text = itemPoJo.getText();
            }
        }
        return text;
    }

    private void setStmtAndOrder(String corpid, PaymentSheetStandardFormatPojo paymentSheetStandardFormatPojo,
                                 List<ContractEntityExt> contractList, List<PaymentEntityExt> paymentList,
                                 Double amount, Integer alone, String uuid) throws XbbException {
        if (Objects.equals(alone, SheetAloneEnum.NORMAL.getCode())) {
            //非合并回款
            if (Objects.nonNull(contractList) && !contractList.isEmpty()) {
                List<OrderSettlementPojo> orderSettlementList = new ArrayList<>();
                ContractEntityExt contract = contractList.get(0);
                JSONObject contractData = contract.getData();
                Double contractAmount = contractData.getDouble(ContractEnum.AMOUNT.getAttr());
                OrderSettlementPojo orderSettlementPojo = new OrderSettlementPojo();
                orderSettlementPojo.setOrderCode(contract.getSerialNo());
                orderSettlementPojo.setSettlementAmount(contractAmount.toString());
                orderSettlementPojo.setOrderPaymentAmount(amount.toString());
                orderSettlementList.add(orderSettlementPojo);
                paymentSheetStandardFormatPojo.setOrderSettlementList(orderSettlementList);
            }
            if (Objects.nonNull(paymentList) && !paymentList.isEmpty()) {
                List<StmtPojo> stmtList = new ArrayList<>();
                PaymentEntityExt payment = paymentList.get(0);
                JSONObject paymentData = payment.getData();
                Double paymentAmount = paymentData.getDouble(PaymentEnum.AMOUNT.getAttr());
                StmtPojo stmtPojo = new StmtPojo();
                stmtPojo.setStmtCode(payment.getSerialNo());
                stmtPojo.setStmtAmount(paymentAmount.toString());
                stmtPojo.setStmtPaymentAmount(amount.toString());
                stmtList.add(stmtPojo);
                paymentSheetStandardFormatPojo.setStmtList(stmtList);
            }
        } else {
            Map<Long, ContractEntityExt> contractMap = new HashMap<>();
            if (Objects.nonNull(contractList) && !contractList.isEmpty()) {
                for (ContractEntityExt contract : contractList) {
                    contractMap.put(contract.getId(), contract);
                }
            }
            Map<Long, PaymentEntityExt> paymentMap = new HashMap<>();
            if (Objects.nonNull(paymentList) && !paymentList.isEmpty()) {
                for (PaymentEntityExt payment : paymentList) {
                    paymentMap.put(payment.getId(), payment);
                }
            }
            List<PaasFormDataEntityExt> childPaymentSheetList = fundHelp.getChildEsDataListByParentUuid(IndexTypeEnum.IDX_SAAS_PAYMENT_SHEET, corpid, uuid, null);
            List<OrderSettlementPojo> orderSettlementList = new ArrayList<>();
            List<StmtPojo> stmtList = new ArrayList<>();
            for (PaasFormDataEntityExt childPaymentSheet : childPaymentSheetList) {
                JSONObject childPaymentSheetData = childPaymentSheet.getData();

                Double childPaymentSheetAmount = childPaymentSheetData.getDouble(PaymentSheetEnum.AMOUNT.getAttr());

                Long paymentId = null;
                JSONArray paymentIdArray = childPaymentSheetData.getJSONArray(PaymentSheetEnum.PAYMENT.getAttr());
                if (Objects.nonNull(paymentIdArray) && !paymentIdArray.isEmpty()) {
                    Integer paymentIdInt = (Integer)paymentIdArray.get(0);
                    paymentId = paymentIdInt.longValue();
                }
                if (Objects.nonNull(paymentId)) {
                    PaymentEntityExt payment = paymentMap.get(paymentId);
                    StmtPojo stmtPojo = new StmtPojo();
                    stmtPojo.setStmtCode(payment.getSerialNo());
                    JSONObject paymentData = payment.getData();
                    Double stmtAmount = paymentData.getDouble(PaymentEnum.AMOUNT.getAttr());
                    stmtPojo.setStmtAmount(stmtAmount.toString());
                    stmtPojo.setStmtPaymentAmount(childPaymentSheetAmount.toString());
                    stmtList.add(stmtPojo);
                }
                Long contractId = null;
                JSONArray contractIdArray = childPaymentSheetData.getJSONArray(PaymentSheetEnum.CONTRACT.getAttr());
                if (Objects.nonNull(contractIdArray) && !contractIdArray.isEmpty()) {
                    Integer contractIdInt = (Integer)contractIdArray.get(0);
                    contractId = contractIdInt.longValue();
                    if (Objects.nonNull(contractId)) {
                        ContractEntityExt contract = contractMap.get(contractId);
                        OrderSettlementPojo orderSettlementPojo = new OrderSettlementPojo();
                        orderSettlementPojo.setOrderCode(contract.getSerialNo());
                        JSONObject contractData = contract.getData();
                        Double settlementAmount = contractData.getDouble(ContractEnum.AMOUNT.getAttr());
                        orderSettlementPojo.setSettlementAmount(settlementAmount.toString());
                        orderSettlementPojo.setOrderPaymentAmount(childPaymentSheetAmount.toString());
                        orderSettlementList.add(orderSettlementPojo);
                    }
                }
            }
            paymentSheetStandardFormatPojo.setStmtList(stmtList);
            paymentSheetStandardFormatPojo.setOrderSettlementList(orderSettlementList);
        }
    }

    /**
     *
     * @param corpid
     * @param groupId 多单位产品组id
     * @return
     * @throws XbbException
     */
    private Map<String, String> getUnitMap4Product(String corpid, Long groupId) throws XbbException {
        Map<String, String> unitMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), corpid);

        //单单位
        if (Objects.isNull(groupId) || Objects.equals(groupId, 0L)) {
            List<ItemPoJo> singleItems = productFieldPojo.getSingleItems();
            singleItems.forEach(item-> unitMap.put(item.getValue().toString(), item.getText()));
            return unitMap;
        }
        //多单位
        List<MultiUnitItemPoJo> multiItems = productFieldPojo.getMultiItems();
        multiItems.forEach(item-> unitMap.put(item.getValue().toString(), item.getBaseName()));
        return unitMap;
    }

    /**
     *
     * @param corpid
     * @return
     * @throws XbbException
     */
    private Map<String, String> getUnitMap4LinkProduct(String corpid) throws XbbException {
        Map<String, String> unitMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), corpid);

        //单单位
        List<ItemPoJo> singleItems = productFieldPojo.getSingleItems();
        singleItems.forEach(item-> unitMap.put(item.getValue().toString(), item.getText()));

        //多单位
        List<UnitItemPoJo> multiItemDataPoJoList = productFieldPojo.getMultiItemDataPoJoList();
        multiItemDataPoJoList.forEach(item-> unitMap.put(item.getValue().toString(), item.getText()));
        return unitMap;
    }

    private Map<Long, String> getUnitMap(String corpid) throws XbbException {
        ProductFieldPojo productFieldPojo = saasFormHelp.getProductFieldPojo(RedisPrefixConstant.PRODUCT_UNIT, ProductEnum.UNIT.getAttr(), corpid);
        List<UnitItemPoJo> multiItemDataPoJoList = productFieldPojo.getMultiItemDataPoJoList();
        Map<Long, String> unitMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        multiItemDataPoJoList.forEach(item-> unitMap.put(item.getValue(), item.getText()));
        return unitMap;
    }
}
